package com.example.kotlindemo.utils
import android.content.Context
import android.util.Log
import com.example.kotlindemo.modules.network.ApiService
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.Response as OkHttpResponse // 区分 Retrofit.Response
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.IOException
import java.util.concurrent.TimeUnit


object ApiClient {

    private const val TAG = "ApiClient"
    private const val CONNECT_TIMEOUT = 10_000L
    private const val READ_TIMEOUT = 10_000L

    // lateinit 允许延迟初始化，但必须在使用前初始化
    private lateinit var retrofit: Retrofit
    private lateinit var okHttpClient: OkHttpClient

    // 保存 Context 用于获取 Token，更好的方式是通过依赖注入传入 TokenProvider
    private var applicationContext: Context? = null

    // 需要在 Application 类或首次使用前调用初始化
    fun init(context: Context) {
        applicationContext = context.applicationContext // 获取 Application Context 防止内存泄漏

        // 1. 配置日志拦截器
        val loggingInterceptor = HttpLoggingInterceptor { message ->
            Log.d(TAG, message)
        }.apply {
            level = HttpLoggingInterceptor.Level.BODY // 设置日志级别
        }

        // 2. 配置认证拦截器 (Kotlin 版本)
        val authInterceptor = Interceptor { chain ->
            val originalRequest = chain.request()
            val requestBuilder = originalRequest.newBuilder()

            // 从 SharedPreferences 或 DataStore 获取 Token
            // 注意：直接在拦截器里访问 Context 和 SharedPreferences 不是最佳实践，
            // 更好的方式是抽象一个 TokenRepository/DataSource 并注入。
            // 这里为了简化，暂时沿用类似你之前的方式，但用了更安全的 Application Context
            val token = getTokenFromStorage(applicationContext) // 实现这个函数

            // 只有当 token 存在且请求的 URL 不是登录接口时才添加 Header
            // 你需要根据实际情况判断哪些接口不需要 token
            if (token != null && !originalRequest.url.encodedPath.endsWith("/login")) {
                // requestBuilder.addHeader("Authorization", "Bearer $token")
            }

            val request = requestBuilder.build()
            val response: OkHttpResponse
            try {
                response = chain.proceed(request)
            } catch (e: IOException) {
                Log.e(TAG, "网络请求失败: ${e.message}")
                throw e // 重新抛出异常，让上层处理
            }


            // 处理 401 错误 (例如：跳转登录页、刷新 Token)
            if (response.code == 401) {
                Log.w(TAG, "收到 401 未授权错误，可能需要重新登录或刷新 Token")
                // 在这里可以添加全局处理逻辑，比如发送一个事件通知 UI 跳转登录页
                // clearTokenAndLogout(applicationContext) // 实现这个函数
            }

            response // 返回响应
        }

        // 3. 配置 OkHttp 客户端
        okHttpClient = OkHttpClient.Builder()
            .connectTimeout(CONNECT_TIMEOUT, TimeUnit.MILLISECONDS)
            .readTimeout(READ_TIMEOUT, TimeUnit.MILLISECONDS)
            .addInterceptor(authInterceptor) // 先添加认证，再添加日志，可以看到完整的请求信息
            .addInterceptor(loggingInterceptor)
            .build()

        // 4. 配置 Retrofit
        retrofit = Retrofit.Builder()
            .baseUrl(ApiService.BASE_URL)
            .client(okHttpClient) // 使用配置好的 OkHttpClient
            .addConverterFactory(GsonConverterFactory.create()) // 添加 Gson 转换器
            .build()
    }

    // 提供 ApiService 实例
    // 使用 lazy 确保线程安全且只创建一次
    val apiService: ApiService by lazy {
        if (!::retrofit.isInitialized) {
            throw IllegalStateException("ApiClient must be initialized by calling init() first.")
        }
        retrofit.create(ApiService::class.java)
    }

    // --- Token 存储/读取/清除 辅助函数 (需要你自己实现) ---
    // 建议使用 Jetpack DataStore 或 SharedPreferences
    private fun getTokenFromStorage(context: Context?): String? {
        if (context == null) return null
        // 示例：使用 SharedPreferences
        val prefs = context.getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE)
        return prefs.getString("access_token", null)
    }

    fun saveTokenToStorage(context: Context?, token: String?) {
        if (context == null) return
        val prefs = context.getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE)
        prefs.edit().putString("access_token", token).apply()
        Log.d(TAG, "Token 保存成功")
    }

    private fun clearTokenAndLogout(context: Context?) {
        if (context == null) return
        val prefs = context.getSharedPreferences("MyAppPrefs", Context.MODE_PRIVATE)
        prefs.edit().remove("access_token").apply()
        Log.d(TAG, "Token 已清除")
        // 这里可以添加跳转到登录页的逻辑，例如通过发送 Broadcast 或使用 Navigation Component
    }
}